﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Xml;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Net;
using System.Web;
using System.IO;
using Transformer.iHunter;

namespace Transformer.iHunter.Plugins.ThuOnlineLearning
{
    public partial class ThuLearningConfigDialog : UserControl, System.Xml.Serialization.IXmlSerializable
    {
        private class CourseInfo
        {
            private string courseId;
            private string courseName;

            public CourseInfo(string id, string name)
            {
                this.courseId = id;
                this.courseName = name;
            }

            public string CourseId
            {
                get { return courseId; }
                set { courseId = value; }
            }
            public string CourseName
            {
                get { return courseName; }
                set { courseName = value; }
            }
        }

        private string courseName = string.Empty;
        private string courseId = string.Empty;
        private string username = string.Empty;
        private string password = string.Empty;

        private bool login = false;
        private bool readxml = false;

        private XmlDocument settings;

        private BackgroundWorker bw;
        private List<CourseInfo> courseinfos;

        public ThuLearningConfigDialog()
        {
            InitializeComponent();

            labelTip.Text = "";

            settings = new XmlDocument();
            settings.LoadXml("<Course><CourseName/><CourseId/><Username/><Password/></Course>");
            checkedListBoxCourse.DisplayMember = "CourseName";

            courseinfos = new List<CourseInfo>();

            bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }

        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            settings.Load(reader);
            textBoxUsername.Text = settings.DocumentElement["Username"].InnerText;
            textBoxPassword.Text = settings.DocumentElement["Password"].InnerText;

            if (textBoxUsername.Text.Length == 0 || textBoxPassword.Text.Length == 0)
                return;
            
            readxml = true;
            try
            {
                if (bw.IsBusy != true)
                {
                    labelTip.Text = "Login...";
                    bw.RunWorkerAsync();
                }
            }
            catch
            {
                labelTip.Text = "Login failed.";
                return;
            }
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            if (login == false || checkedListBoxCourse.CheckedItems.Count == 0)
                throw new ArgumentException("Please input username and password to login, and select a course.");

            settings.DocumentElement["Username"].InnerText = textBoxUsername.Text;
            settings.DocumentElement["Password"].InnerText = textBoxPassword.Text;
            settings.DocumentElement["CourseName"].InnerText = ((CourseInfo)checkedListBoxCourse.CheckedItems[0]).CourseName;
            settings.DocumentElement["CourseId"].InnerText = ((CourseInfo)checkedListBoxCourse.CheckedItems[0]).CourseId;

            settings.WriteTo(writer);
        }

        #endregion

        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            login = false;
            Login();
        }

        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (login)
            {
                labelTip.Text = "Login successfully.";
                checkedListBoxCourse.Items.Clear();
                foreach (CourseInfo ci in courseinfos)
                    checkedListBoxCourse.Items.Add(ci, false);

                if (readxml)
                {
                    for (int i = 0; i < this.checkedListBoxCourse.Items.Count; i++)
                    {
                        if (((CourseInfo)checkedListBoxCourse.Items[i]).CourseId != settings.DocumentElement["CourseId"].InnerText)
                            this.checkedListBoxCourse.SetItemCheckState(i, System.Windows.Forms.CheckState.Unchecked);
                        else
                            this.checkedListBoxCourse.SetItemCheckState(i, System.Windows.Forms.CheckState.Checked);
                    }
                }
                else
                {
                    if (checkedListBoxCourse.Items.Count != 0)
                        checkedListBoxCourse.SetItemChecked(0, true);
                }
            }
            else
            {
                labelTip.Text = "Login failed.";
                checkedListBoxCourse.Items.Clear();
            }
        }

        private void Login()
        {
            byte[] data = Encoding.UTF8.GetBytes("userid=" + textBoxUsername.Text + "&userpass=" + textBoxPassword.Text + "&submit1=%B5%C7%C2%BC");

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://learn.tsinghua.edu.cn/use_go.jsp");
            request.Method = "POST";
            request.Accept = @"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
            request.ContentType = @"application/x-www-form-urlencoded";
            request.ContentLength = data.Length;

            CookieContainer cookies = new CookieContainer();
            request.CookieContainer = cookies;

            Stream reqStream = null;
            HttpWebResponse response = null;
            StreamReader reader = null;
            string responseContent = null;

            try
            {
                reqStream = request.GetRequestStream();
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();

                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                responseContent = reader.ReadToEnd();

                reader.Close();
                response.Close();

                //检查是否登录成功
                if (!responseContent.Contains("/lesson/teacher/main.jsp"))
                    throw new Exception();

                //获得各个课程的信息对应的课程信息
                request = (HttpWebRequest)WebRequest.Create(@"http://learn.tsinghua.edu.cn/lesson/student/MyCourse.jsp?typepage=1");
                request.CookieContainer = cookies;

                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                responseContent = reader.ReadToEnd();

                Regex r = new Regex(@"course_id=(?<Id>\d*)[^>]*>\s*(?<Title>[^(]*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                MatchCollection matches = r.Matches(responseContent);

                courseinfos.Clear();
                foreach (Match m in matches)
                {
                    courseinfos.Add(new CourseInfo(m.Groups["Id"].Value, m.Groups["Title"].Value));
                }

                reader.Close();
                response.Close();

                request = (HttpWebRequest)WebRequest.Create(@"http://learn.tsinghua.edu.cn/lesson/student/MyCourse.jsp?typepage=2");
                request.CookieContainer = cookies;

                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                responseContent = reader.ReadToEnd();
                
                r = new Regex(@"course_id=(?<Id>\d*)[^>]*>\s*(?<Title>[^(]*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                matches = r.Matches(responseContent);
                foreach (Match m in matches)
                {
                    courseinfos.Add(new CourseInfo(m.Groups["Id"].Value, m.Groups["Title"].Value));
                }

                reader.Close();
                response.Close();

                login = true;
            }
            catch
            {
                if (reader != null)
                    reader.Close();
                if (response != null)
                    response.Close();
                labelWarning.Text = "无法获得课程列表！请检查用户名、密码以及网络连接是否正确。";
                login = false;
            }
        }

        private void buttonLogin_Click(object sender, EventArgs e)
        {
            if (textBoxUsername.Text.Length == 0)
            {
                labelTip.Text = "Input username.";
                return;
            }
            if (textBoxPassword.Text.Length == 0)
            {
                labelTip.Text = "Input password.";
                return;
            }
            
            readxml = false;
            if (bw.IsBusy != true)
            {
                labelTip.Text = "Login...";
                bw.RunWorkerAsync();
            }
        }

        private void checkedListBoxCourse_ItemCheck(object sender, System.Windows.Forms.ItemCheckEventArgs e)
        {
            if (this.checkedListBoxCourse.CheckedItems.Count > 0)
            {
                for (int i = 0; i < this.checkedListBoxCourse.Items.Count; i++)
                {
                    if (i != e.Index)
                        this.checkedListBoxCourse.SetItemCheckState(i, System.Windows.Forms.CheckState.Unchecked);
                }
            }
        }

    }
}
